import React, { useMemo, useCallback, useEffect, useRef } from 'react';
import clsname from '../lib/clsname';
const comClsName = `${clsname.name}-image-viewer`;
function genTransformStyle(imageStyle) {
    const { scale, rotate } = imageStyle;
    return `rotate(${rotate}deg) scale(${scale || 1})`;
}
function initMouseState() {
    return {
        moveX: 0,
        moveY: 0,
        isMouseDown: false,
        startX: 0,
        startY: 0,
    };
}
function ImageViewer(props) {
    const { invoice, setToolFns } = props;
    const mouseState = useRef(initMouseState());
    const imageStyle = useRef({
        scale: 1,
        top: 0,
        left: 0,
        rotate: 0,
    })
    const imgRef = useRef(null);
    const containerRef = useRef(null);
    const image = useMemo(() => {
        return invoice?.attachmentFiles?.[0] || {}
    }, [invoice])
    /* 放大 */
    const zoomInFn = useCallback(() => {
        imageStyle.current.scale = imageStyle.current.scale * 1.2;
        imgRef.current.style.transform = genTransformStyle(imageStyle.current);
    }, []);
    /* 缩小 */
    const zoomOutFn = useCallback(() => {
        imageStyle.current.scale = imageStyle.current.scale * 0.8;
        imgRef.current.style.transform = genTransformStyle(imageStyle.current);
    }, []);
    // * 左旋转90度
    const handleRotateLeft = useCallback(() => {
        imageStyle.current.rotate += -90;
        imgRef.current.style.transform = genTransformStyle(imageStyle.current);
    }, []);
    // * 右旋转90度
    const handleRotateRight = useCallback(() => {
        imageStyle.current.rotate += 90;
        imgRef.current.style.transform = genTransformStyle(imageStyle.current);
    }, []);
    /* 处理鼠标按下事件 */
    const handleMouseDown = useCallback((e) => {
        e.preventDefault();
        e.stopPropagation();
        mouseState.current.isMouseDown = true;
        mouseState.current.startX = e.pageX;
        mouseState.current.startY = e.pageY;
        containerRef.current.style.cursor = 'grabbing';
    }, []);
    /* 处理鼠标放开事件 */
    const handleMouseMoveCancel = useCallback(() => {
        //* 当鼠标点击放开后，需要把当前的图片的transform.translateX/Y的值记录下来 
        if (mouseState.current.isMouseDown) {
            imageStyle.current.left += mouseState.current.moveX;
            imageStyle.current.top += mouseState.current.moveY;
            mouseState.current = initMouseState();
            containerRef.current.style.cursor = 'grab';
        }
    }, []);
    const handleMouseMove = useCallback((e) => {
        if (mouseState.current.isMouseDown) {
            //* moveX的算法，求取一个鼠标移动的相对位置，可以通过事件中pageX，减去鼠标按下后当时状态的pageX来计算相对的偏移X具体，同理可以Y轴的偏移据里
            let moveX = e.pageX - mouseState.current?.startX;
            let moveY = e.pageY - mouseState.current?.startY;
            mouseState.current.moveX = moveX;
            mouseState.current.moveY = moveY;
            let imageOffsetX = imageStyle.current.left + moveX;
            let imageOffsetY = imageStyle.current.top + moveY;
            imgRef.current.style.top = `${imageOffsetY}px`;
            imgRef.current.style.left = `${imageOffsetX}px`;
        }
    }, []);
    // * 处理图片加载完后初始化图片大小
    const handleImageOnLoad = () => {
        let heigthScaleRatio = Math.round(containerRef.current.offsetHeight * 100 / imgRef.current.naturalHeight) / 100;
        let widthScaleRatio = Math.round(containerRef.current.offsetWidth * 100 / imgRef.current.naturalWidth) / 100;
        let scaleRatio = widthScaleRatio > heigthScaleRatio ? heigthScaleRatio : widthScaleRatio;
        if (scaleRatio < 1) {
            imageStyle.current.scale = imageStyle.current.scale * scaleRatio;
            imgRef.current.style.transform = genTransformStyle(imageStyle.current);
        }
    }
    // * 处理鼠标滚轮改变图片大小的功能
    const handleMouseWheel = (e) => {
        e.preventDefault();
        // * 判断滚轮方向（上或下）
        if (e.deltaY > 0) {
            // * 鼠标滚轮往下滚动
            zoomOutFn();
        } else if (e.deltaY < 0) {
            // * 鼠标滚轮往上滚动
            zoomInFn();
        }
    }

    useEffect(() => {
        setToolFns(fns => {
            return {
                ...fns,
                zoomin: zoomInFn,
                zoomout: zoomOutFn,
                'rotate-left': handleRotateLeft,
                'rotate-right': handleRotateRight,
            }
        })
    }, [setToolFns, zoomInFn, zoomOutFn, handleRotateLeft, handleRotateRight]);

    return (
        <div
            className={comClsName}
            ref={containerRef}
            onMouseUp={handleMouseMoveCancel}
            onMouseDown={handleMouseDown}
            onMouseMove={handleMouseMove}
            onMouseLeave={handleMouseMoveCancel}
            onWheel={handleMouseWheel}
        >
            <img src={image.originalUrl} ref={imgRef} style={{ position: 'relative' }} onLoad={handleImageOnLoad} />
        </div>
    )
}
export default ImageViewer;